package com.tanchengjin.admin.controller;

import com.google.code.kaptcha.Constants;
import com.tanchengjin.admin.SystemConstants;
import com.tanchengjin.admin.exception.ApplicationException;
import com.tanchengjin.admin.model.dao.AdminUserMapper;
import com.tanchengjin.admin.model.pojo.AdminUser;
import com.tanchengjin.admin.service.AdminOperationLogService;
import com.tanchengjin.admin.service.AdministratorService;
import com.tanchengjin.admin.utils.OperationLogUtil;
import com.tanchengjin.admin.utils.ServerResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * 管理员认证控制器
 * @author tanchengjin
 */
@Controller
@RequestMapping("${app.admin.prefix}/auth")
public class AdminAuthenticationController {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Autowired
    private AdministratorService administratorService;

    @Autowired
    private AdminOperationLogService adminOperationLogService;

    @Value("${app.admin.prefix}")
    private String adminPrefix;

    @RequestMapping(value = "/login", method = {RequestMethod.GET})
    public String loginView(HttpServletRequest request) {
        Object attribute = request.getSession().getAttribute(SystemConstants.adminUserSessionKey);
        if (attribute != null) {
            return "redirect:" + adminPrefix;
        }
        return "/admin/auth/login";
    }

    @RequestMapping(value = "/login", method = {RequestMethod.POST})
    @ResponseBody
    public ServerResponse login(String username, String password, String code, HttpServletRequest request, HttpServletResponse response) {
        validateCaptcha(code, request);
        if (username == null || password == null) {
            return ServerResponse.responseWithFailureMessage("用户名或密码不允许为空");
        }

        AdminUser adminUser = adminUserMapper.selectByUsername(username);
        if (adminUser == null) {
            return ServerResponse.responseWithFailureMessage("用户名或密码错误!");
        }


        if (passwordEncoder.matches(password, adminUser.getPassword())) {
            AdminUser adminUserInSession = new AdminUser();
            BeanUtils.copyProperties(adminUser, adminUserInSession);
            adminUserInSession.setPassword(null);
            adminUserInSession.setSalt(null);
            //写入session
            request.getSession().setAttribute(SystemConstants.adminUserSessionKey, adminUserInSession);


            //设置rememberToken
            try {
                long time = new Date().getTime();
                String s = adminUser.getName() + ":"+time;
                String rememberToken = DigestUtils.md5DigestAsHex(s.getBytes(StandardCharsets.UTF_8));
                rememberMeSetup(request, response, rememberToken);
                AdminUser tmp = new AdminUser();
                tmp.setId(adminUser.getId());
                tmp.setRememberToken(rememberToken);
                adminUserMapper.updateByPrimaryKeySelective(tmp);
                OperationLogUtil.write(request,"登陆成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
            //full info
//            AdministratorVO admin = administratorService.getAdmin();
//            request.getSession().setAttribute(SystemConstants.adminSessionKey, admin);

            return ServerResponse.responseWithSuccess();
        } else {
            return ServerResponse.responseWithFailureMessage("用户名或密码错误!");
        }
    }

    private boolean validateCaptcha(String code, HttpServletRequest request) {
        if (code == null) throw new ApplicationException("验证码不允许为空");

        String attribute = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (attribute == null) throw new ApplicationException("验证码不存在");

        if (!code.equalsIgnoreCase(attribute)) throw new ApplicationException("验证码错误");

        return true;
    }

    @RequestMapping(value = "/logout", method = {RequestMethod.POST})
    @ResponseBody
    public ServerResponse logout(HttpServletRequest request) {
        request.getSession().removeAttribute(SystemConstants.adminUserSessionKey);
        return ServerResponse.responseWithSuccess();
    }

    private boolean rememberMeSetup(HttpServletRequest request, HttpServletResponse response, String rememberMeToken) {
        boolean rememberMe = (request.getParameter("rememberMe") != null);
        if (rememberMe) {
            Cookie cookie = new Cookie("member_me", rememberMeToken);
            cookie.setPath(request.getContextPath() + "/");
            //有效期七天
            cookie.setMaxAge(60 * 60 * 24 * 7);
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
            return true;
        }
        return false;
    }
}
